package model.components.networks.network;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import model.components.links.comparator.LinkNumberComparator;
import model.components.links.link.Link;
import model.components.nodes.comparator.NodeNumberComparator;
import model.components.nodes.node.Node;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.EdgeType;

public class Network
{
	public static final String ACCEPTED_STATE  = "Accepted";
	public static final String REJECTED_STATE  = "Rejected";
	public static final String AVAILABLE_STATE = "Available";
	public static final String READY_STATE     = "Ready";
	
	private String namePrefix;
	public String getNamePrefix(){ return namePrefix; }
	public void setNamePrefix( String namePrefix ){ this.namePrefix = namePrefix; }
	
	private int number;
	public int getNumber(){ return number; }
	public void setNumber( int number )
	{
		this.number = number;
		this.setName( this.getNamePrefix() + number );
	}
	
	private String name;
	public String getName(){ return name; }
	public void setName( String name ){ this.name = name; }
	
	private int timeStamp;
	public int getTimeStamp(){ return timeStamp; }
	public void setTimeStamp( int timeStamp )
	{
		this.timeStamp = timeStamp;
		
		for( Node node: this.getNodes() )
			node.setTimeStamp( timeStamp );
		
		for( Link link: this.getLinks() )
			link.setTimeStamp( timeStamp );
	}
	
	private Graph< Node, Link > graph;
	public Graph< Node, Link > getGraph(){ return graph; }
	public void setGraph( Graph< Node, Link > graph )
	{
		this.graph = graph;
		this.setEndPoints();
	}
	
	private Layout< Node, Link > layout;
	public Layout< Node, Link > getLayout(){ return layout; }
	public void setLayout( Layout< Node, Link > layout ){ this.layout = layout; }
	
	private String state;
	public String getState(){ return state; }
	public void setState( String state ){ this.state = state; }
	
	private boolean change = false;
	public boolean isChange(){ return change; }
	public void setChange( boolean change ){ this.change = change; }

	public Network( String namePrefix, int number, Graph< Node, Link > graph )
	{
		this.setNamePrefix( namePrefix );
		this.setNumber( number );
		this.setGraph( graph );
		
		this.setLayout( new CircleLayout< Node, Link >( this.getGraph() ) );
		this.setState( Network.AVAILABLE_STATE );
		this.setTimeStamp( -1 );
	}
	
	public List< Node > getNodes()
	{
		List< Node > nodes = new ArrayList< Node >();
		
		for( Node node: this.getGraph().getVertices() )
			nodes.add( node );
		
		Collections.sort( nodes, new NodeNumberComparator() );
		
		return nodes;
	}
	
    public List< Link > getLinks()
    {
    	List< Link > links = new ArrayList< Link >();
		
		for( Link link: this.getGraph().getEdges() )
			links.add( link );
		
		Collections.sort( links, new LinkNumberComparator() );
    	
    	return links;
	}
	
    public void addLinkAndNodes( Link link, Node firstNode, Node secondNode )
    {
    	this.getGraph().addEdge( link, firstNode, secondNode, EdgeType.UNDIRECTED );
    	this.getGraph().addVertex( firstNode );
    	this.getGraph().addVertex( secondNode );
    	
    	this.setEndPoints();
    }
    
	private void setEndPoints()
	{
		for( Link link: this.getGraph().getEdges() )
		{
			link.setFirstNode(  this.getGraph().getEndpoints( link ).getFirst() );
			link.setSecondNode( this.getGraph().getEndpoints( link ).getSecond() );
		}
	}

}
